package com.ruoyi.eqmonitor;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ruoyi.eqmonitor.dispose.domain.OpentsdbTags;
import com.ruoyi.eqmonitor.domain.BizDeviceHistory;
import com.ruoyi.eqmonitor.domain.OptDevice;
import com.ruoyi.eqmonitor.dtos.OptDeviceDto;
import com.ruoyi.eqmonitor.service.IBizDeviceHistoryService;
import com.ruoyi.eqmonitor.service.IOptDeviceService;
import com.ruoyi.eqmonitor.utils.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.nio.reactor.IOReactorException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opentsdb.client.OpenTSDBClient;
import org.opentsdb.client.bean.request.Query;
import org.opentsdb.client.bean.request.SubQuery;
import org.opentsdb.client.bean.response.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class ExportMonitorData {

    @Resource
    private OpenTSDBUtils openTSDBUtils;

    @Resource
    private IBizDeviceHistoryService bizDeviceHistoryService;
    /**
     * opentsdb查询client
     */
    private OpenTSDBClient queryClient;

    @Resource
    private IOptDeviceService iOptDeviceService;

    @Before
    public void init() throws IOReactorException {
        try {
            queryClient = openTSDBUtils.readClient();
        } catch (IOReactorException e) {
            log.error("创建opentsdb查询失败");
            throw e;
        }
    }

    @After
    public void close() {
        if (queryClient != null) {
            //关闭连接
            try {
                queryClient.gracefulClose();
            } catch (IOException e) {
                log.error("关闭opentsdb连接失败");
            }
        }
    }

    /**
     * 一号泵站周围的那几个设备01
     */
    @Test
    public void exportBZ1SheBei01() {
        List<String> snCodes = ListUtil.of(
                "RTB906"
        );
        snCodes.parallelStream().forEach(snCode -> {
            OptDeviceDto deviceByCode = iOptDeviceService.getDeviceByCode(snCode);
            // 1. 创建snCodeFilter和monitorCode过滤器
            SubQuery.Filter snCodeFilter = OpenTSDBUtils.createSnCodeFilter(snCode);
            DateTime startTime = DateUtil.parse("2022-11-14 00:00:00");
            DateTime endTime = DateUtil.parse("2022-12-14 23:59:59");
            // 2. 计算时间
            long startDateTime = OpenTSDBUtils.serializedTime(startTime);
            long endDateTime = OpenTSDBUtils.serializedTime(endTime);

            // 3. 子查询
            SubQuery sub = SubQuery
                    .metric(openTSDBUtils.getMetric())
                    // 不聚合
                    .aggregator(SubQuery.Aggregator.NONE)
                    .filter(snCodeFilter)
                    .build();

            // 4. 查询主体
            Query queryParams = Query
                    // 开始时间 秒
                    .begin(startDateTime)
                    // 结束时间 秒
                    .end(endDateTime)
                    // 时区相关
                    .useCalendar().timezone(OpenTSDBUtils.OPENTSDB_TIMEZONE)
                    // 子查询
                    .sub(sub)
                    .build();

            try {
                // 5. 进行查询
                List<QueryResult> resultList = queryClient.query(queryParams);
                List<Map<String, Object>> excelList = new ArrayList<>();
                for (QueryResult queryResult : resultList) {
                    // 目的是将tags的base64转换为原始的字符串
                    OpentsdbTags opentsdbTags = OpenTSDBUtils.decodeToBean(queryResult.getTags());
//                log.info("最新监测指标查询结果: tags: {}\n dps: {}", opentsdbTags, queryResult.getDps());
                    queryResult.getDps().forEach((stamp, number) -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("设备编码", opentsdbTags.getSnCode());
                        map.put("设备类型", opentsdbTags.getEquipmentTypeCode());
                        map.put("设备类型名称", opentsdbTags.getEquipmentType());
                        map.put("监测指标", opentsdbTags.getMonitorCode());
                        map.put("监测指标名称", opentsdbTags.getMonitorName());
                        map.put("时间(秒级时间戳)", stamp);
                        map.put("时间(时间)", OpenTSDBUtils.deserialize(stamp));
                        map.put("数据值", number);
                        map.put("单位", opentsdbTags.getDataUnit());
                        excelList.add(map);
                    });
                }
                Map<String, List<Map<String, Object>>> group = excelList.stream().collect(Collectors.groupingBy(map -> MapUtil.getStr(map, "监测指标")));
                group.entrySet().parallelStream().forEach(entry -> {
                    String key = entry.getKey();
                    Constant.MonitorInfo monitorInfoByCode = Constant.MonitorInfo.getMonitorInfoByCode(key);
                    monitorInfoByCode = monitorInfoByCode == null ? Constant.MonitorInfo.getParamInfoByCode(key) : monitorInfoByCode;
                    String monitorName = monitorInfoByCode == null ? key : monitorInfoByCode.getName();
                    String name = deviceByCode.getDeviceCode() + "_" + Constant.EquipmentType.getValueByCode(deviceByCode.getDeviceType()) + "_" + monitorName + "_" + startTime.toString("yyyy-MM-dd") + "_" + endTime.toString("yyyy-MM-dd");
                    ExcelWriter writer = ExcelUtil.getWriter("D:\\desktop\\deviceExport\\" + name + ".xlsx");
                    ExcelWriter write = writer.write(
                            ListUtil.sort(entry.getValue(), (o1, o2) -> NumberUtil.compare(MapUtil.getLong(o1, "时间(秒级时间戳)"), MapUtil.getLong(o2, "时间(秒级时间戳)"))),
                            true
                    );
                    System.out.println(excelList.size());
                    write.flush();
                    write.close();
                });
//            log.info("列表查询结果: {}", JSONUtil.toJsonStr(resultList));
            } catch (IOException | ExecutionException | InterruptedException e) {
                log.error("查询opentsdb失败", e);
            }
        });
    }


    /**
     * 一号泵站周围的那几个设备02
     * update biz_device_history_copy2 set monitor_data = round(monitor_data/100, 3) where device_code in('4TRV24', '290TEN', 'FFP051')
     */
    @Test
    public void exportBZ1SheBei() {
        // cod设备
        List<String> codSnCodes =  ListUtil.of( "7V7ET1", "3M1Y4H", "5V11PJ", "T067PZ", "931JSZ");
        // 液位设备
        List<String> snCodes = ListUtil.of( "ZQ922P", "RTB906", "4TRV24", "FFP051","290TEN" );
        snCodes.forEach(snCode -> {
            saveHistoryByCode(snCode, Constant.MonitorInfo.M_0x05D1.getCode());
        });
        codSnCodes.forEach(snCode -> {
            saveHistoryByCode(snCode, Constant.MonitorInfo.M_0x0527.getCode());
        });
    }

    public void saveHistoryByCode(String snCode, String monitorCode) {
        OptDeviceDto deviceByCode = iOptDeviceService.getDeviceByCode(snCode);
        // 1. 创建snCodeFilter和monitorCode过滤器
        SubQuery.Filter snCodeFilter = OpenTSDBUtils.createSnCodeFilter(snCode);
        SubQuery.Filter monitorCodeFilter = OpenTSDBUtils.createMonitorCodeFilter(monitorCode);
        DateTime startTime = DateUtil.parse("2022-11-14 00:00:00");
        DateTime endTime = DateUtil.endOfDay(DateUtil.offsetDay(new DateTime(), -1));
        // 2. 计算时间
        long startDateTime = OpenTSDBUtils.serializedTime(startTime);
        long endDateTime = OpenTSDBUtils.serializedTime(endTime);

        // 3. 子查询
        SubQuery sub = SubQuery
                .metric(openTSDBUtils.getMetric())
                // 不聚合
                .aggregator(SubQuery.Aggregator.NONE)
                .downsample("1dc-avg")
                .filter(snCodeFilter)
                .filter(monitorCodeFilter)
                .build();

        // 4. 查询主体
        Query queryParams = Query
                // 开始时间 秒
                .begin(startDateTime)
                // 结束时间 秒
                .end(endDateTime)
                // 时区相关
                .useCalendar().timezone(OpenTSDBUtils.OPENTSDB_TIMEZONE)
                // 子查询
                .sub(sub)
                .build();

        try {
            // 5. 进行查询
            List<QueryResult> resultList = queryClient.query(queryParams);
//                List<Map<String, Object>> excelList = new ArrayList<>();
            log.info("设备编码: {} - {}, 数据条数: {}", snCode, monitorCode, resultList.size());
            for (QueryResult queryResult : resultList) {
                // 目的是将tags的base64转换为原始的字符串
                OpentsdbTags opentsdbTags = OpenTSDBUtils.decodeToBean(queryResult.getTags());
//                log.info("最新监测指标查询结果: tags: {}\n dps: {}", opentsdbTags, queryResult.getDps());
                queryResult.getDps().forEach((stamp, number) -> {
                    String monitorUnit = opentsdbTags.getDataUnit(), monitorQuotaName = opentsdbTags.getMonitorName();
                    if (opentsdbTags.getDataUnit() == null) {
                        Constant.MonitorInfo info = Constant.MonitorInfo.getMonitorInfoByCode(opentsdbTags.getMonitorCode());
                        if (info != null) {
                            monitorQuotaName = info.getName();
                            monitorUnit = info.getUnit();
                        }
                    }
                    BizDeviceHistory bizDeviceHistory = new BizDeviceHistory();
                    bizDeviceHistory.setDeviceCode(deviceByCode.getDeviceCode());
                    bizDeviceHistory.setDeviceTypeName(Constant.EquipmentType.getValueByCode(deviceByCode.getDeviceType()));
                    bizDeviceHistory.setMonitorUnit(monitorUnit);
                    bizDeviceHistory.setMonitorQuota(opentsdbTags.getMonitorCode());
                    bizDeviceHistory.setMonitorData(NumberUtil.round(number.doubleValue(), 3).toString());
                    bizDeviceHistory.setStamp(stamp.toString());
                    bizDeviceHistory.setDeviceType(deviceByCode.getDeviceType());
                    bizDeviceHistory.setMonitorQuotaName(monitorQuotaName);
                    bizDeviceHistory.setDate(DateUtil.parseDateTime(OpenTSDBUtils.deserialize(stamp)));
                    bizDeviceHistoryService.save(bizDeviceHistory);
                });
            }
        } catch (IOException | ExecutionException | InterruptedException e) {
            log.error("{}-{}查询opentsdb失败", snCode, monitorCode, e);
        }
    }


    @Test
    public void saveHistoryByCode() {
        // 1. 创建snCodeFilter和monitorCode过滤器
        SubQuery.Filter snCodeFilter = OpenTSDBUtils.createSnCodeFilter("931JSZ");
        SubQuery.Filter monitorCodeFilter = OpenTSDBUtils.createMonitorCodeFilter(Constant.MonitorInfo.M_0x0527.getCode());
        DateTime startTime = DateUtil.parse("2022-12-23 00:00:00");
        DateTime endTime = DateUtil.parse("2022-12-23 23:59:59");
        // 2. 计算时间
        long startDateTime = OpenTSDBUtils.serializedTime(startTime);
        long endDateTime = OpenTSDBUtils.serializedTime(endTime);

        // 3. 子查询
        SubQuery sub = SubQuery
                .metric(openTSDBUtils.getMetric())
                // 不聚合
                .aggregator(SubQuery.Aggregator.NONE)
                .downsample("1dc-avg")
                .filter(snCodeFilter)
                .filter(monitorCodeFilter)
                .build();

        // 4. 查询主体
        Query queryParams = Query
                // 开始时间 秒
                .begin(startDateTime)
                // 结束时间 秒
                .end(endDateTime)
                // 时区相关
                .useCalendar().timezone(OpenTSDBUtils.OPENTSDB_TIMEZONE)
                // 子查询
                .sub(sub)
                .build();

        try {
            // 5. 进行查询
            List<QueryResult> resultList = queryClient.query(queryParams);
//                List<Map<String, Object>> excelList = new ArrayList<>();
            for (QueryResult queryResult : resultList) {
                // 目的是将tags的base64转换为原始的字符串
                OpentsdbTags opentsdbTags = OpenTSDBUtils.decodeToBean(queryResult.getTags());
//                log.info("最新监测指标查询结果: tags: {}\n dps: {}", opentsdbTags, queryResult.getDps());
                queryResult.getDps().forEach((stamp, number) -> {
                    String monitorUnit = opentsdbTags.getDataUnit(), monitorQuotaName = opentsdbTags.getMonitorName();
                    if (opentsdbTags.getDataUnit() == null) {
                        Constant.MonitorInfo info = Constant.MonitorInfo.getMonitorInfoByCode(opentsdbTags.getMonitorCode());
                        if (info != null) {
                            monitorQuotaName = info.getName();
                            monitorUnit = info.getUnit();
                        }
                    }
                    BizDeviceHistory bizDeviceHistory = new BizDeviceHistory();
                    bizDeviceHistory.setDeviceCode("931JSZ");
                    bizDeviceHistory.setDeviceTypeName(Constant.EquipmentType.getValueByCode("SR500-L-Y0-SNY"));
                    bizDeviceHistory.setMonitorUnit(monitorUnit);
                    bizDeviceHistory.setMonitorQuota(opentsdbTags.getMonitorCode());
                    bizDeviceHistory.setMonitorData(NumberUtil.round(number.doubleValue(), 3).toString());
                    bizDeviceHistory.setStamp(stamp.toString());
                    bizDeviceHistory.setDeviceType("SR500-L-Y0-SNY");
                    bizDeviceHistory.setMonitorQuotaName(monitorQuotaName);
                    bizDeviceHistory.setDate(DateUtil.parseDateTime(OpenTSDBUtils.deserialize(stamp)));
                    bizDeviceHistoryService.save(bizDeviceHistory);
                });
            }
        } catch (IOException | ExecutionException | InterruptedException e) {
            log.error("查询opentsdb失败", e);
        }
    }

    /**
     * 7个河道的最近7天的液位和流量
     */
    @Test
    public void export7River() {
        List<String> snCodes = ListUtil.of(
                // 7个河道监测站
                "6SQK78", "GG8N76", "67WW0R", "K61P0F", "LP9F04", "M17WP3", "PA674U"
        );
        snCodes.parallelStream().forEach(snCode -> {
            OptDeviceDto deviceByCode = iOptDeviceService.getDeviceByCode(snCode);
            // 1. 创建snCodeFilter和monitorCode过滤器
            SubQuery.Filter snCodeFilter = OpenTSDBUtils.createSnCodeFilter(snCode);
            // 河道监测的液位和流量
            SubQuery.Filter monitorCodeFilter = OpenTSDBUtils.createMonitorCodeFilter("0x05D1", "0x0592");
            DateTime startTime = DateUtil.parse("2022-12-08 00:00:00");
            DateTime endTime = DateUtil.parse("2022-12-14 23:59:59");
            // 2. 计算时间
            long startDateTime = OpenTSDBUtils.serializedTime(startTime);
            long endDateTime = OpenTSDBUtils.serializedTime(endTime);

            // 3. 子查询
            SubQuery sub = SubQuery
                    .metric(openTSDBUtils.getMetric())
                    // 不聚合
                    .aggregator(SubQuery.Aggregator.NONE)
                    .filter(snCodeFilter)
                    .filter(monitorCodeFilter)
                    .build();

            // 4. 查询主体
            Query queryParams = Query
                    // 开始时间 秒
                    .begin(startDateTime)
                    // 结束时间 秒
                    .end(endDateTime)
                    // 时区相关
                    .useCalendar().timezone(OpenTSDBUtils.OPENTSDB_TIMEZONE)
                    // 子查询
                    .sub(sub)
                    .build();

            try {
                // 5. 进行查询
                List<QueryResult> resultList = queryClient.query(queryParams);
                List<Map<String, Object>> excelList = new ArrayList<>();
                for (QueryResult queryResult : resultList) {
                    // 目的是将tags的base64转换为原始的字符串
                    OpentsdbTags opentsdbTags = OpenTSDBUtils.decodeToBean(queryResult.getTags());
//                log.info("最新监测指标查询结果: tags: {}\n dps: {}", opentsdbTags, queryResult.getDps());
                    queryResult.getDps().forEach((stamp, number) -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("设备编码", opentsdbTags.getSnCode());
                        map.put("设备类型", opentsdbTags.getEquipmentTypeCode());
                        map.put("设备类型名称", opentsdbTags.getEquipmentType());
                        map.put("监测指标", opentsdbTags.getMonitorCode());
                        map.put("监测指标名称", opentsdbTags.getMonitorName());
                        map.put("时间(秒级时间戳)", stamp);
                        map.put("时间(时间)", OpenTSDBUtils.deserialize(stamp));
                        map.put("数据值", number);
                        map.put("单位", opentsdbTags.getDataUnit());
                        excelList.add(map);
                    });
                }
                Map<String, List<Map<String, Object>>> group = excelList.stream().collect(Collectors.groupingBy(map -> MapUtil.getStr(map, "监测指标")));
                group.entrySet().parallelStream().forEach(entry -> {
                    String key = entry.getKey();
                    Constant.MonitorInfo monitorInfoByCode = Constant.MonitorInfo.getMonitorInfoByCode(key);
                    monitorInfoByCode = monitorInfoByCode == null ? Constant.MonitorInfo.getParamInfoByCode(key) : monitorInfoByCode;
                    String monitorName = monitorInfoByCode == null ? key : monitorInfoByCode.getName();
                    String name = deviceByCode.getDeviceCode() + "_" + Constant.EquipmentType.getValueByCode(deviceByCode.getDeviceType()) + "_" + monitorName + "_" + startTime.toString("yyyy-MM-dd") + "_" + endTime.toString("yyyy-MM-dd");
                    ExcelWriter writer = ExcelUtil.getWriter("D:\\desktop\\hdExport\\" + name + ".xlsx");
                    ExcelWriter write = writer.write(
                            ListUtil.sort(entry.getValue(), (o1, o2) -> NumberUtil.compare(MapUtil.getLong(o1, "时间(秒级时间戳)"), MapUtil.getLong(o2, "时间(秒级时间戳)"))),
                            true
                    );
                    System.out.println(excelList.size());
                    write.flush();
                    write.close();
                });
//            log.info("列表查询结果: {}", JSONUtil.toJsonStr(resultList));
            } catch (IOException | ExecutionException | InterruptedException e) {
                log.error("查询opentsdb失败", e);
            }
        });
    }

    static Map<String, String> bzLLMap = new HashMap<>();
    static Map<String, String> bzSZMap = new HashMap<>();
    static Map<String, String> bzJGMap = new HashMap<>();
    static {
        bzLLMap.put("RTB906", "1号泵站"); // 流量监测仪
        bzSZMap.put("931JSZ", "1号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("0PG79G", "1号泵站"); // 井盖状态监测仪

        bzLLMap.put("53CLR5", "2号泵站"); // 流量监测仪
        bzSZMap.put("6G03ZP", "2号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("ANB823", "2号泵站"); // 井盖状态监测仪

        bzLLMap.put("M166EA", "3号泵站"); // 流量监测仪
        bzSZMap.put("195LNZ", "3号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("WWA239", "3号泵站"); // 井盖状态监测仪

        bzLLMap.put("J001EJ", "4号泵站"); // 流量监测仪
        bzSZMap.put("114WJU", "4号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("RRP836", "4号泵站"); // 井盖状态监测仪

        bzLLMap.put("3B94ES", "5号泵站"); // 流量监测仪
        bzSZMap.put("85D2UL", "5号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("F220PD", "5号泵站"); // 井盖状态监测仪

        bzLLMap.put("5J71UF", "6号泵站"); // 流量监测仪
        bzSZMap.put("3TBZ55", "6号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("P726JY", "6号泵站"); // 井盖状态监测仪

        bzLLMap.put("9B59FN", "7号泵站"); // 流量监测仪
        bzSZMap.put("9B59FN", "7号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("3T23QX", "7号泵站"); // 井盖状态监测仪

        bzLLMap.put("U4D2E8", "滨海1号泵站"); // 流量监测仪
        bzSZMap.put("1U30CX", "滨海1号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("1ZZ38W", "滨海1号泵站"); // 井盖状态监测仪

        bzLLMap.put("2CJJ65", "滨海2号泵站"); // 流量监测仪
        bzSZMap.put("K927KP", "滨海2号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("C6K5F3", "滨海2号泵站"); // 井盖状态监测仪

        bzLLMap.put("H8V48B", "滨海3号泵站"); // 流量监测仪
        bzSZMap.put("6N1F9Z", "滨海3号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("G90K0L", "滨海3号泵站"); // 井盖状态监测仪

        bzLLMap.put("PE3P64", "滨海4号泵站"); // 流量监测仪
        bzSZMap.put("WN63P6", "滨海4号泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("1WK11Q", "滨海4号泵站"); // 井盖状态监测仪

        bzLLMap.put("LW33S4", "黄琅盐场泵站"); // 流量监测仪
        bzSZMap.put("CB4E85", "黄琅盐场泵站"); // 原位水质监测仪（COD+氨氮）
        bzJGMap.put("8Y22AP", "黄琅盐场泵站"); // 井盖状态监测仪
    }
    /**
     * 7个河道的最近7天的液位和流量
     */
    @Test
    public void exportBz() {
        bzLLMap.entrySet().parallelStream().forEach(mapping -> {
            String snCode = mapping.getKey();
            String bzName = mapping.getValue();
            OptDeviceDto deviceByCode = iOptDeviceService.getDeviceByCode(snCode);
            // 1. 创建snCodeFilter和monitorCode过滤器
            SubQuery.Filter snCodeFilter = OpenTSDBUtils.createSnCodeFilter(snCode);
            // 河道监测的液位和流量
            SubQuery.Filter monitorCodeFilter = OpenTSDBUtils.createMonitorCodeFilter("0x0592", "0x056F");
            DateTime startTime = DateUtil.parse("2022-11-25 00:00:00");
            DateTime endTime = DateUtil.parse("2022-12-22 23:59:59");
            // 2. 计算时间
            long startDateTime = OpenTSDBUtils.serializedTime(startTime);
            long endDateTime = OpenTSDBUtils.serializedTime(endTime);

            // 3. 子查询
            SubQuery sub = SubQuery
                    .metric(openTSDBUtils.getMetric())
                    // 不聚合
                    .aggregator(SubQuery.Aggregator.NONE)
                    .filter(snCodeFilter)
                    .filter(monitorCodeFilter)
                    .build();

            // 4. 查询主体
            Query queryParams = Query
                    // 开始时间 秒
                    .begin(startDateTime)
                    // 结束时间 秒
                    .end(endDateTime)
                    // 时区相关
                    .useCalendar().timezone(OpenTSDBUtils.OPENTSDB_TIMEZONE)
                    // 子查询
                    .sub(sub)
                    .build();

            try {
                // 5. 进行查询
                List<QueryResult> resultList = queryClient.query(queryParams);
                List<Map<String, Object>> excelList = new ArrayList<>();
                for (QueryResult queryResult : resultList) {
                    // 目的是将tags的base64转换为原始的字符串
                    OpentsdbTags opentsdbTags = OpenTSDBUtils.decodeToBean(queryResult.getTags());
//                log.info("最新监测指标查询结果: tags: {}\n dps: {}", opentsdbTags, queryResult.getDps());
                    queryResult.getDps().forEach((stamp, number) -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("设备编码", opentsdbTags.getSnCode());
                        map.put("设备类型", opentsdbTags.getEquipmentTypeCode());
                        map.put("设备类型名称", opentsdbTags.getEquipmentType());
                        map.put("监测指标", opentsdbTags.getMonitorCode());
                        map.put("监测指标名称", opentsdbTags.getMonitorName());
                        map.put("时间(秒级时间戳)", stamp);
                        map.put("时间(时间)", OpenTSDBUtils.deserialize(stamp));
                        map.put("数据值", number);
                        map.put("单位", opentsdbTags.getDataUnit());
                        map.put("所属泵站", bzName);
                        excelList.add(map);
                    });
                }
                Map<String, List<Map<String, Object>>> group = excelList.stream().collect(Collectors.groupingBy(map -> MapUtil.getStr(map, "监测指标")));
                group.entrySet().parallelStream().forEach(entry -> {
                    String key = entry.getKey();
                    Constant.MonitorInfo monitorInfoByCode = Constant.MonitorInfo.getMonitorInfoByCode(key);
                    monitorInfoByCode = monitorInfoByCode == null ? Constant.MonitorInfo.getParamInfoByCode(key) : monitorInfoByCode;
                    String monitorName = monitorInfoByCode == null ? key : monitorInfoByCode.getName();
                    String name = bzName + "_" + deviceByCode.getDeviceCode() + "_" + Constant.EquipmentType.getValueByCode(deviceByCode.getDeviceType()) + "_" + monitorName + "_" + startTime.toString("yyyy-MM-dd") + "_" + endTime.toString("yyyy-MM-dd");
                    ExcelWriter writer = ExcelUtil.getWriter("D:\\desktop\\bzExport\\" + name + ".xlsx");
                    ExcelWriter write = writer.write(
                            ListUtil.sort(entry.getValue(), (o1, o2) -> NumberUtil.compare(MapUtil.getLong(o1, "时间(秒级时间戳)"), MapUtil.getLong(o2, "时间(秒级时间戳)"))),
                            true
                    );
                    System.out.println(excelList.size());
                    write.flush();
                    write.close();
                });
//            log.info("列表查询结果: {}", JSONUtil.toJsonStr(resultList));
            } catch (IOException | ExecutionException | InterruptedException e) {
                log.error("查询opentsdb失败", e);
            }
        });
    }

}
